"""BLE Authentication Service.

Provides GATT characteristics for secure authentication, device pairing,
and session management over BLE connections.
"""

import asyncio
import json
import logging
import struct
import time
from typing import Dict, List, Optional, Callable, Any
from enum import Enum

from ..security.auth_manager import AuthManager, AuthState, AuthResult, AuthChallenge
from ..security.key_manager import SessionKeyManager, KeyExchangeData
from ..security.secure_transport import SecureTransport, MessageType, SecurityLevel
from ..security.security_audit import SecurityAudit, EventType, Severity

logger = logging.getLogger(__name__)


# Service and Characteristic UUIDs
AUTH_SERVICE_UUID = "0000FF40-0000-1000-8000-00805F9B34FB"
AUTH_CHALLENGE_UUID = "0000FF41-0000-1000-8000-00805F9B34FB"     # Read, Notify
AUTH_RESPONSE_UUID = "0000FF42-0000-1000-8000-00805F9B34FB"      # Write
KEY_EXCHANGE_UUID = "0000FF43-0000-1000-8000-00805F9B34FB"       # Read, Write
SECURE_DATA_UUID = "0000FF44-0000-1000-8000-00805F9B34FB"        # Read, Write, Notify
AUTH_STATUS_UUID = "0000FF45-0000-1000-8000-00805F9B34FB"        # Read, Notify


class AuthCommand(Enum):
    """Authentication control commands."""
    START_AUTH = 0x01        # Start authentication
    SUBMIT_PIN = 0x02        # Submit PIN response
    REQUEST_PAIRING = 0x03   # Request device pairing
    START_KEY_EXCHANGE = 0x04 # Start key exchange
    COMPLETE_KEY_EXCHANGE = 0x05  # Complete key exchange
    REVOKE_SESSION = 0x06    # Revoke session
    RESET_AUTH = 0x07        # Reset authentication


class AuthService:
    """BLE Authentication Service implementation."""
    
    def __init__(self, auth_manager: AuthManager, 
                 key_manager: SessionKeyManager,
                 secure_transport: SecureTransport,
                 security_audit: SecurityAudit):
        """Initialize authentication service.
        
        Args:
            auth_manager: Authentication manager instance
            key_manager: Session key manager instance  
            secure_transport: Secure transport instance
            security_audit: Security audit instance
        """
        self.auth_manager = auth_manager
        self.key_manager = key_manager
        self.secure_transport = secure_transport
        self.security_audit = security_audit
        
        # Service state
        self.active_challenges: Dict[str, AuthChallenge] = {}
        self.active_exchanges: Dict[str, KeyExchangeData] = {}
        
        # Notification callback
        self.notify_callback: Optional[Callable[[str, bytes], None]] = None
        
        # Service registration data
        self.service_data = self._create_service_definition()
        
        # Status notification interval
        self.status_notify_interval = 60  # 1 minute
        self.status_task: Optional[asyncio.Task] = None
        
        # Setup auth manager callbacks
        self.auth_manager.on_auth_success = self._on_auth_success
        self.auth_manager.on_auth_failure = self._on_auth_failure
        self.auth_manager.on_device_paired = self._on_device_paired
        
        logger.info("AuthService initialized")
    
    def _create_service_definition(self) -> Dict[str, Any]:
        """Create GATT service definition.
        
        Returns:
            Service definition dictionary
        """
        return {
            "uuid": AUTH_SERVICE_UUID,
            "primary": True,
            "characteristics": [
                {
                    "uuid": AUTH_CHALLENGE_UUID,
                    "flags": ["read", "notify"],
                    "value": bytearray(256),  # Challenge data
                    "descriptors": [
                        {
                            "uuid": "00002902-0000-1000-8000-00805F9B34FB",  # CCC
                            "flags": ["read", "write"],
                            "value": bytearray([0x00, 0x00])
                        }
                    ]
                },
                {
                    "uuid": AUTH_RESPONSE_UUID,
                    "flags": ["write"],
                    "value": bytearray(128),   # PIN response
                    "descriptors": []
                },
                {
                    "uuid": KEY_EXCHANGE_UUID,
                    "flags": ["read", "write"],
                    "value": bytearray(512),   # Key exchange data
                    "descriptors": []
                },
                {
                    "uuid": SECURE_DATA_UUID,
                    "flags": ["read", "write", "notify"],
                    "value": bytearray(1024),  # Encrypted data
                    "descriptors": [
                        {
                            "uuid": "00002902-0000-1000-8000-00805F9B34FB",  # CCC
                            "flags": ["read", "write"],
                            "value": bytearray([0x00, 0x00])
                        }
                    ]
                },
                {
                    "uuid": AUTH_STATUS_UUID,
                    "flags": ["read", "notify"],
                    "value": bytearray(64),    # Status information
                    "descriptors": [
                        {
                            "uuid": "00002902-0000-1000-8000-00805F9B34FB",  # CCC
                            "flags": ["read", "write"],
                            "value": bytearray([0x00, 0x00])
                        }
                    ]
                }
            ]
        }
    
    async def start(self):
        """Start authentication service."""
        # Start periodic status notifications
        self.status_task = asyncio.create_task(self._status_notification_loop())
        
        # Setup secure transport message handlers
        self.secure_transport.register_message_handler(
            MessageType.HANDSHAKE, self._handle_handshake_message
        )
        
        await self.security_audit.log_system_event(
            "auth_service_started", Severity.LOW
        )
        
        logger.info("AuthService started")
    
    async def stop(self):
        """Stop authentication service."""
        if self.status_task:
            self.status_task.cancel()
            try:
                await self.status_task
            except asyncio.CancelledError:
                pass
        
        await self.security_audit.log_system_event(
            "auth_service_stopped", Severity.LOW
        )
        
        logger.info("AuthService stopped")
    
    # GATT Characteristic Handlers
    
    async def handle_read_auth_challenge(self, device_id: str = None) -> bytes:
        """Handle read from AUTH_CHALLENGE characteristic.
        
        Args:
            device_id: Optional device ID for targeted challenge
            
        Returns:
            Challenge data
        """
        try:
            if not device_id:
                # Return generic challenge status
                return self._format_challenge_status()
            
            # Check for active challenge
            challenge = None
            for ch in self.active_challenges.values():
                if ch.device_id == device_id:
                    challenge = ch
                    break
            
            if not challenge:
                return b'{"error": "No active challenge"}'
            
            challenge_data = {
                "challenge_id": challenge.challenge_id,
                "expires_at": int(challenge.expires_at),
                "attempts_left": challenge.attempts_left,
                "pin_length": 6
            }
            
            return json.dumps(challenge_data).encode('utf-8')[:256]
            
        except Exception as e:
            logger.error(f"Error reading auth challenge: {e}")
            return b'{"error": "Challenge read failed"}'
    
    async def handle_write_auth_response(self, value: bytes, 
                                       device_id: str = None) -> bool:
        """Handle write to AUTH_RESPONSE characteristic.
        
        Args:
            value: Authentication response bytes
            device_id: Device making the request
            
        Returns:
            True if handled successfully
        """
        try:
            if not value or not device_id:
                return False
            
            # Parse authentication command
            command = AuthCommand(value[0])
            params = value[1:] if len(value) > 1 else b''
            
            if command == AuthCommand.START_AUTH:
                return await self._handle_start_auth(device_id, params)
            
            elif command == AuthCommand.SUBMIT_PIN:
                return await self._handle_submit_pin(device_id, params)
            
            elif command == AuthCommand.REQUEST_PAIRING:
                return await self._handle_request_pairing(device_id, params)
            
            elif command == AuthCommand.REVOKE_SESSION:
                return await self._handle_revoke_session(device_id, params)
            
            elif command == AuthCommand.RESET_AUTH:
                return await self._handle_reset_auth(device_id)
            
            else:
                logger.warning(f"Unknown auth command: {command}")
                return False
                
        except Exception as e:
            logger.error(f"Error handling auth response: {e}")
            return False
    
    async def handle_read_key_exchange(self, device_id: str = None) -> bytes:
        """Handle read from KEY_EXCHANGE characteristic.
        
        Args:
            device_id: Device requesting key exchange data
            
        Returns:
            Key exchange data
        """
        try:
            if not device_id:
                return b'{"error": "Device ID required"}'
            
            # Find active key exchange for device
            exchange = None
            session_id = None
            
            # Get session for device
            session = self.auth_manager.get_session_by_device(device_id)
            if session:
                session_id = session.session_id
                
                # Look for exchange
                for ex in self.active_exchanges.values():
                    if ex.session_id == session_id:
                        exchange = ex
                        break
            
            if not exchange:
                return b'{"error": "No active key exchange"}'
            
            exchange_data = {
                "exchange_id": exchange.exchange_id,
                "public_key": exchange.public_key.hex(),
                "algorithm": exchange.algorithm,
                "expires_at": int(exchange.expires_at)
            }
            
            return json.dumps(exchange_data).encode('utf-8')[:512]
            
        except Exception as e:
            logger.error(f"Error reading key exchange: {e}")
            return b'{"error": "Key exchange read failed"}'
    
    async def handle_write_key_exchange(self, value: bytes, 
                                      device_id: str = None) -> bool:
        """Handle write to KEY_EXCHANGE characteristic.
        
        Args:
            value: Key exchange command bytes
            device_id: Device making the request
            
        Returns:
            True if handled successfully
        """
        try:
            if not value or not device_id:
                return False
            
            command = AuthCommand(value[0])
            params = value[1:]
            
            if command == AuthCommand.START_KEY_EXCHANGE:
                return await self._handle_start_key_exchange(device_id)
            
            elif command == AuthCommand.COMPLETE_KEY_EXCHANGE:
                return await self._handle_complete_key_exchange(device_id, params)
            
            else:
                logger.warning(f"Invalid key exchange command: {command}")
                return False
                
        except Exception as e:
            logger.error(f"Error handling key exchange: {e}")
            return False
    
    async def handle_read_secure_data(self, device_id: str = None) -> bytes:
        """Handle read from SECURE_DATA characteristic.
        
        Args:
            device_id: Device requesting secure data
            
        Returns:
            Encrypted data or status
        """
        try:
            if not device_id:
                return b'{"error": "Device ID required"}'
            
            session = self.auth_manager.get_session_by_device(device_id)
            if not session or session.state != AuthState.PAIRED:
                return b'{"error": "Authentication required"}'
            
            # Return secure channel status
            status_data = {
                "secure_channel": True,
                "encryption": "AES-128-GCM",
                "session_id": session.session_id,
                "timestamp": int(time.time())
            }
            
            return json.dumps(status_data).encode('utf-8')[:1024]
            
        except Exception as e:
            logger.error(f"Error reading secure data: {e}")
            return b'{"error": "Secure data read failed"}'
    
    async def handle_write_secure_data(self, value: bytes, 
                                     device_id: str = None) -> bool:
        """Handle write to SECURE_DATA characteristic.
        
        Args:
            value: Encrypted message bytes
            device_id: Device sending the data
            
        Returns:
            True if handled successfully
        """
        try:
            if not value or not device_id:
                return False
            
            session = self.auth_manager.get_session_by_device(device_id)
            if not session or session.state != AuthState.PAIRED:
                logger.warning(f"Secure data from unauthenticated device: {device_id}")
                return False
            
            # Process encrypted message through secure transport
            message = await self.secure_transport.receive_message(value)
            if message:
                logger.debug(f"Received secure message from {device_id}: "
                           f"{len(message.payload)} bytes")
                return True
            
            return False
            
        except Exception as e:
            logger.error(f"Error handling secure data: {e}")
            return False
    
    async def handle_read_auth_status(self, device_id: str = None) -> bytes:
        """Handle read from AUTH_STATUS characteristic.
        
        Args:
            device_id: Device requesting status
            
        Returns:
            Authentication status data
        """
        try:
            if device_id:
                # Device-specific status
                session = self.auth_manager.get_session_by_device(device_id)
                device_info = self.auth_manager.device_registry.get_device(device_id)
                
                if session:
                    status_data = struct.pack(
                        '>BBIIB',
                        session.state.value,           # Auth state (1 byte)
                        len(session.permissions),      # Permission count (1 byte)
                        int(session.expires_at),       # Expires at (4 bytes)
                        int(session.last_activity),    # Last activity (4 bytes)
                        1 if device_info and device_info.is_blocked else 0  # Blocked (1 byte)
                    )
                else:
                    # No session
                    status_data = struct.pack('>BBIIB', 0, 0, 0, 0, 
                                           1 if device_info and device_info.is_blocked else 0)
            else:
                # Global status
                stats = self.auth_manager.get_statistics()
                status_data = struct.pack(
                    '>BBBB',
                    stats["auth_manager"]["active_sessions"],     # Active sessions
                    stats["auth_manager"]["active_challenges"],   # Active challenges
                    stats["device_registry"]["total_devices"],   # Total devices
                    stats["device_registry"]["blocked_devices"]  # Blocked devices
                )
            
            return status_data
            
        except Exception as e:
            logger.error(f"Error reading auth status: {e}")
            return b'\\x00' * 11  # Return zeros on error
    
    # Command Handlers
    
    async def _handle_start_auth(self, device_id: str, params: bytes) -> bool:
        """Handle start authentication command."""
        try:
            # Create authentication challenge
            challenge = await self.auth_manager.create_auth_challenge(device_id)
            self.active_challenges[challenge.challenge_id] = challenge
            
            # Send challenge notification
            await self._send_challenge_notification(challenge)
            
            await self.security_audit.log_auth_attempt(
                device_id, False, details={"action": "challenge_created"}
            )
            
            logger.info(f"Authentication started for device: {device_id}")
            return True
            
        except Exception as e:
            logger.error(f"Start auth error: {e}")
            return False
    
    async def _handle_submit_pin(self, device_id: str, params: bytes) -> bool:
        """Handle PIN submission."""
        try:
            # Parse PIN response
            data = json.loads(params.decode('utf-8'))
            challenge_id = data.get('challenge_id')
            pin_code = data.get('pin_code')
            
            if not challenge_id or not pin_code:
                return False
            
            # Verify authentication
            result, session = await self.auth_manager.verify_auth_response(
                challenge_id, pin_code
            )
            
            # Clean up challenge
            self.active_challenges.pop(challenge_id, None)
            
            # Send result notification
            await self._send_auth_result_notification(device_id, result, session)
            
            success = result == AuthResult.SUCCESS
            await self.security_audit.log_auth_attempt(
                device_id, success, 
                session.session_id if session else None,
                {"result": result.name}
            )
            
            return True
            
        except Exception as e:
            logger.error(f"Submit PIN error: {e}")
            return False
    
    async def _handle_request_pairing(self, device_id: str, params: bytes) -> bool:
        """Handle device pairing request."""
        try:
            # Parse pairing request
            data = json.loads(params.decode('utf-8'))
            device_name = data.get('device_name', 'Unknown Device')
            mac_address = data.get('mac_address', '00:00:00:00:00:00')
            trust_level = data.get('trust_level', 1)
            
            # Pair device
            device_info = await self.auth_manager.pair_device(
                device_id, device_name, mac_address, trust_level
            )
            
            # Send pairing confirmation
            await self._send_pairing_notification(device_id, True, device_info)
            
            await self.security_audit.log_pairing_event(
                device_id, "success", True, {
                    "device_name": device_name,
                    "trust_level": trust_level
                }
            )
            
            logger.info(f"Device paired: {device_id} ({device_name})")
            return True
            
        except Exception as e:
            logger.error(f"Request pairing error: {e}")
            await self.security_audit.log_pairing_event(
                device_id, "failure", False, {"error": str(e)}
            )
            return False
    
    async def _handle_start_key_exchange(self, device_id: str) -> bool:
        """Handle start key exchange command."""
        try:
            session = self.auth_manager.get_session_by_device(device_id)
            if not session:
                return False
            
            # Create key exchange
            exchange = await self.key_manager.create_key_exchange(session.session_id)
            self.active_exchanges[exchange.exchange_id] = exchange
            
            # Send key exchange notification
            await self._send_key_exchange_notification(device_id, exchange)
            
            await self.security_audit.log_key_operation(
                "exchange_started", exchange.exchange_id, session.session_id
            )
            
            logger.info(f"Key exchange started: {exchange.exchange_id}")
            return True
            
        except Exception as e:
            logger.error(f"Start key exchange error: {e}")
            return False
    
    async def _handle_complete_key_exchange(self, device_id: str, 
                                          params: bytes) -> bool:
        """Handle complete key exchange command."""
        try:
            # Parse key exchange completion
            data = json.loads(params.decode('utf-8'))
            exchange_id = data.get('exchange_id')
            peer_public_key = bytes.fromhex(data.get('public_key', ''))
            
            if not exchange_id or not peer_public_key:
                return False
            
            # Complete key exchange
            session_key = await self.key_manager.complete_key_exchange(
                exchange_id, peer_public_key
            )
            
            # Clean up exchange
            self.active_exchanges.pop(exchange_id, None)
            
            # Send completion notification
            await self._send_key_exchange_complete_notification(
                device_id, session_key
            )
            
            await self.security_audit.log_key_operation(
                "exchange_completed", session_key.key_id,
                session_key.key_id  # Use key_id as session reference
            )
            
            logger.info(f"Key exchange completed: {session_key.key_id}")
            return True
            
        except Exception as e:
            logger.error(f"Complete key exchange error: {e}")
            return False
    
    async def _handle_revoke_session(self, device_id: str, params: bytes) -> bool:
        """Handle session revocation command."""
        try:
            session = self.auth_manager.get_session_by_device(device_id)
            if session:
                await self.auth_manager.revoke_session(session.session_id)
                await self.security_audit.log_session_event(
                    EventType.SESSION_EXPIRED, session.session_id, device_id
                )
                
            logger.info(f"Session revoked for device: {device_id}")
            return True
            
        except Exception as e:
            logger.error(f"Revoke session error: {e}")
            return False
    
    async def _handle_reset_auth(self, device_id: str) -> bool:
        """Handle authentication reset command."""
        try:
            # Revoke all access for device
            await self.auth_manager.revoke_device_access(device_id)
            
            # Clean up service state
            challenges_to_remove = []
            for ch_id, challenge in self.active_challenges.items():
                if challenge.device_id == device_id:
                    challenges_to_remove.append(ch_id)
            
            for ch_id in challenges_to_remove:
                del self.active_challenges[ch_id]
            
            await self.security_audit.log_security_violation(
                "auth_reset", device_id, Severity.MEDIUM
            )
            
            logger.info(f"Authentication reset for device: {device_id}")
            return True
            
        except Exception as e:
            logger.error(f"Reset auth error: {e}")
            return False
    
    # Event Handlers
    
    def _on_auth_success(self, device_id: str, session):
        """Handle authentication success event."""
        asyncio.create_task(self._send_auth_status_notification(device_id))
    
    def _on_auth_failure(self, device_id: str, result: AuthResult):
        """Handle authentication failure event.""" 
        asyncio.create_task(self._send_auth_status_notification(device_id))
    
    def _on_device_paired(self, device_id: str, device_info):
        """Handle device pairing event."""
        asyncio.create_task(self._send_auth_status_notification(device_id))
    
    # Notification Methods
    
    def _format_challenge_status(self) -> bytes:
        """Format generic challenge status."""
        status = {
            "active_challenges": len(self.active_challenges),
            "service_ready": True,
            "timestamp": int(time.time())
        }
        return json.dumps(status).encode('utf-8')
    
    async def _send_challenge_notification(self, challenge: AuthChallenge):
        """Send challenge notification."""
        try:
            challenge_data = {
                "challenge_id": challenge.challenge_id,
                "expires_at": int(challenge.expires_at),
                "attempts_left": challenge.attempts_left,
                "pin_length": 6
            }
            
            data = json.dumps(challenge_data).encode('utf-8')[:256]
            await self._send_notification(AUTH_CHALLENGE_UUID, data)
            
        except Exception as e:
            logger.error(f"Error sending challenge notification: {e}")
    
    async def _send_auth_result_notification(self, device_id: str, 
                                           result: AuthResult, session=None):
        """Send authentication result notification."""
        try:
            result_data = {
                "device_id": device_id,
                "result": result.name,
                "success": result == AuthResult.SUCCESS,
                "session_id": session.session_id if session else None,
                "timestamp": int(time.time())
            }
            
            data = json.dumps(result_data).encode('utf-8')[:256]
            await self._send_notification(AUTH_CHALLENGE_UUID, data)
            
        except Exception as e:
            logger.error(f"Error sending auth result notification: {e}")
    
    async def _send_pairing_notification(self, device_id: str, success: bool, 
                                       device_info=None):
        """Send pairing notification."""
        try:
            pairing_data = {
                "device_id": device_id,
                "success": success,
                "trust_level": device_info.trust_level if device_info else 0,
                "timestamp": int(time.time())
            }
            
            data = json.dumps(pairing_data).encode('utf-8')[:256]
            await self._send_notification(AUTH_STATUS_UUID, data)
            
        except Exception as e:
            logger.error(f"Error sending pairing notification: {e}")
    
    async def _send_key_exchange_notification(self, device_id: str,
                                            exchange: KeyExchangeData):
        """Send key exchange notification."""
        try:
            exchange_data = {
                "device_id": device_id,
                "exchange_id": exchange.exchange_id,
                "public_key": exchange.public_key.hex(),
                "algorithm": exchange.algorithm,
                "expires_at": int(exchange.expires_at)
            }
            
            data = json.dumps(exchange_data).encode('utf-8')[:512]
            await self._send_notification(KEY_EXCHANGE_UUID, data)
            
        except Exception as e:
            logger.error(f"Error sending key exchange notification: {e}")
    
    async def _send_key_exchange_complete_notification(self, device_id: str,
                                                     session_key):
        """Send key exchange completion notification."""
        try:
            complete_data = {
                "device_id": device_id,
                "key_id": session_key.key_id,
                "algorithm": session_key.algorithm.value,
                "expires_at": int(session_key.expires_at),
                "success": True
            }
            
            data = json.dumps(complete_data).encode('utf-8')[:512]
            await self._send_notification(KEY_EXCHANGE_UUID, data)
            
        except Exception as e:
            logger.error(f"Error sending key exchange complete notification: {e}")
    
    async def _send_auth_status_notification(self, device_id: str):
        """Send authentication status notification."""
        try:
            status_data = await self.handle_read_auth_status(device_id)
            await self._send_notification(AUTH_STATUS_UUID, status_data)
            
        except Exception as e:
            logger.error(f"Error sending auth status notification: {e}")
    
    async def _send_notification(self, characteristic_uuid: str, data: bytes):
        """Send notification for a characteristic.
        
        Args:
            characteristic_uuid: UUID of characteristic
            data: Notification data
        """
        if self.notify_callback:
            self.notify_callback(characteristic_uuid, data)
    
    # Background Tasks
    
    async def _status_notification_loop(self):
        """Background status notification loop."""
        while True:
            try:
                await asyncio.sleep(self.status_notify_interval)
                
                # Send global status notification
                status_data = await self.handle_read_auth_status()
                await self._send_notification(AUTH_STATUS_UUID, status_data)
                
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error(f"Status notification loop error: {e}")
    
    def _handle_handshake_message(self, message):
        """Handle handshake message from secure transport."""
        try:
            # Process handshake data
            handshake_data = json.loads(message.payload.decode('utf-8'))
            device_id = handshake_data.get('device_id')
            
            if device_id:
                logger.debug(f"Received handshake from device: {device_id}")
                # Update device activity
                self.auth_manager.device_registry.update_device_activity(device_id)
            
        except Exception as e:
            logger.error(f"Handshake message error: {e}")
    
    # Service Interface
    
    def set_notify_callback(self, callback: Callable[[str, bytes], None]):
        """Set notification callback.
        
        Args:
            callback: Callback function for notifications (uuid, data)
        """
        self.notify_callback = callback
    
    def get_service_definition(self) -> Dict[str, Any]:
        """Get GATT service definition.
        
        Returns:
            Service definition for registration
        """
        return self.service_data
    
    def get_auth_statistics(self) -> Dict[str, Any]:
        """Get authentication service statistics.
        
        Returns:
            Service statistics
        """
        return {
            "auth_service": {
                "is_running": self.status_task is not None and not self.status_task.done(),
                "active_challenges": len(self.active_challenges),
                "active_exchanges": len(self.active_exchanges),
                "notification_interval": self.status_notify_interval
            },
            "auth_manager": self.auth_manager.get_statistics(),
            "key_manager": self.key_manager.get_statistics(),
            "secure_transport": self.secure_transport.get_statistics()
        }
    
    async def cleanup(self):
        """Clean up service resources."""
        await self.stop()
        self.active_challenges.clear()
        self.active_exchanges.clear()
        logger.info("AuthService cleanup completed")


# Example usage and testing
if __name__ == "__main__":
    import asyncio
    import tempfile
    
    from ..security.auth_manager import AuthManager
    from ..security.key_manager import SessionKeyManager
    from ..security.secure_transport import SecureTransport
    from ..security.security_audit import SecurityAudit
    
    async def test_auth_service():
        """Test authentication service functionality."""
        # Create temporary directory for audit logs
        with tempfile.TemporaryDirectory() as temp_dir:
            # Create components
            auth_manager = AuthManager()
            key_manager = SessionKeyManager()
            secure_transport = SecureTransport(key_manager)
            security_audit = SecurityAudit(temp_dir)
            
            # Create auth service
            auth_service = AuthService(
                auth_manager, key_manager, secure_transport, security_audit
            )
            
            # Mock notification callback
            notifications = []
            def notify_callback(uuid, data):
                notifications.append((uuid, data))
            
            auth_service.set_notify_callback(notify_callback)
            
            # Start all services
            await auth_manager.start()
            await key_manager.start()
            await secure_transport.start()
            await security_audit.start()
            await auth_service.start()
            
            try:
                # Test service definition
                service_def = auth_service.get_service_definition()
                print(f"Service UUID: {service_def['uuid']}")
                print(f"Characteristics: {len(service_def['characteristics'])}")
                
                device_id = "test_device_001"
                
                # Test authentication flow
                print(f"\n=== Testing Authentication Flow ===")
                
                # Start authentication
                start_cmd = bytes([AuthCommand.START_AUTH.value])
                success = await auth_service.handle_write_auth_response(
                    start_cmd, device_id
                )
                print(f"Start auth: {'success' if success else 'failed'}")
                
                # Check for challenge
                challenge_data = await auth_service.handle_read_auth_challenge(device_id)
                print(f"Challenge data: {challenge_data.decode('utf-8', errors='ignore')[:100]}...")
                
                # Submit PIN (simulate)
                if success:
                    pin_response = {
                        "challenge_id": "test_challenge",  # Would be from actual challenge
                        "pin_code": "123456"
                    }
                    pin_cmd = bytes([AuthCommand.SUBMIT_PIN.value]) + json.dumps(pin_response).encode()
                    
                    # This would fail without real challenge, but tests the flow
                    pin_success = await auth_service.handle_write_auth_response(
                        pin_cmd, device_id
                    )
                    print(f"PIN submit: {'success' if pin_success else 'expected failure'}")
                
                # Test status reading
                status_data = await auth_service.handle_read_auth_status(device_id)
                print(f"Status data length: {len(status_data)} bytes")
                
                # Test key exchange
                print(f"\n=== Testing Key Exchange ===")
                key_cmd = bytes([AuthCommand.START_KEY_EXCHANGE.value])
                key_success = await auth_service.handle_write_key_exchange(
                    key_cmd, device_id
                )
                print(f"Key exchange start: {'success' if key_success else 'expected failure'}")
                
                # Wait for notifications
                await asyncio.sleep(1)
                print(f"\nReceived {len(notifications)} notifications")
                
                # Get statistics
                stats = auth_service.get_auth_statistics()
                print(f"\nService statistics:")
                print(f"  Active challenges: {stats['auth_service']['active_challenges']}")
                print(f"  Active exchanges: {stats['auth_service']['active_exchanges']}")
                
            finally:
                # Cleanup
                await auth_service.cleanup()
                await security_audit.cleanup()
                await secure_transport.cleanup()
                await key_manager.cleanup()
                await auth_manager.cleanup()
    
    # Run test
    asyncio.run(test_auth_service())